
#include "GameObjects\World.h"
#include "RoomManager.h"
#include "ItemManager.h"

#include "Input.h"
#include "Player.h"
#include "Time.h"

#include "CommandManager.h"
#include "Commands\Movement.h"
#include "Commands\Vision.h"
#include "Commands\Collecting.h"
#include "Commands\HoldItem.h"
#include "Commands\ThrowItem.h"
#include "Commands\ItemInventory.h"
#include "Commands\UseBlade.h"

#include <iostream>

#include <iostream>
#include <filesystem>

int main(int /*argc*/, char** argv)
{
	//Convert to string, then trim away the executable filename and the build type directory (Debug/MinSizeRel/Release/etc)
	std::string argv_dir(argv[0]);
	argv_dir = argv_dir.substr(0, argv_dir.find_last_of("\\"));
	argv_dir = argv_dir.substr(0, argv_dir.find_last_of("\\"));

	//Set up commands
	Movement::Init();
	Vision::Init();
	Collecting::Init();
	HoldItem::Init();
	ThrowItem::Init();
	ItemInventory::Init();
	UseBlade::Init();

    ItemManager::getSingleton()->init(argv_dir + "\\resources\\Items");
	RoomManager::getSingleton()->init(argv_dir + "\\resources\\Rooms");
	World::getSingleton()->init(RoomManager::getSingleton()->getSpawn());

	//Set up input handling thread
    Input::getSingleton()->init();

	//Set up player
	auto player_character = std::make_shared<Character>("ned", "the conqueror");
	auto player = std::make_shared<Player>(player_character, World::getSingleton()->getStartRoom());
	player->initialize();

	Time::init();
	std::string command_str;
    bool command_line_start = true;

	//Start the main loop of the game
	while(true)
	{
        if(command_line_start && Input::getSingleton()->isBlocked() == false)
        {
            std::cout << "> ";
            command_line_start = false;
        }

		if(Input::getSingleton()->isReadReady())
			command_str = Input::getSingleton()->getLine();

		if(command_str == "quit")
		{
			std::cout << "Do you really want to quit?" << std::endl;
			break;
		}

		//If we got a command from player input
		if(command_str.empty() == false)
		{
			std::vector<std::string> args;
			const CommandPtr &command = CommandManager::getSingleton()->getCommand(command_str, args);
			if(command)
				player->handle(command, args);
			else
				std::cout << "What?" << std::endl;
            command_line_start = true;
		}

		//Handle timestep
		auto tick = Time::tick();

		//Update world from player's perspective
		World::getSingleton()->setCurrentClock(Time::getCurrent());
		player->update(tick);

		if(command_str.empty() == false)
			command_str = std::string();
	}
	Input::getSingleton()->Join();
}
